/**
 * @file		dd_pmc_ctc.h
 * @brief		CTC (Cycle Time Counter) driver
 * @note		None
 * @attention	None
 * 
 * <B><I>Copyright 2016 Socionext Inc.</I></B>
 */

/** @weakgroup dd_pmc_ctc_overview
@{
	CM0 PMC - CTC (Cycle Time Counter) Driver.<br>
	<br>
	Cycle Time Counter counts up using the reference clock during the given observed clock cycles.<br>
@}*//* --- end of dd_pmc_ctc_overview */

/** @weakgroup dd_pmc_ctc_sequence
@{
	- @ref dd_pmc_ctc_sequence_sect
	- @ref dd_pmc_ctc_sample_sect
	@section dd_pmc_ctc_sequence_sect	Sequence example of start CTC.
	@image html dd_pmc_ctc.png
	<br>
	<hr>
	@section dd_pmc_ctc_sample_sect		Sample of "Operating Procedure for Cycle Time Counter".
    @code
	VOID cycle_time_counter_callback(VOID)
	{
		INT32			ret;
		ULONG			counter_value;
		
		// Get Counter value.
		ret = Dd_PMC_CTC_Get_Counter_Value(&counter_value);
		if (ret == D_DDIM_OK) {
			Ddim_Print(("CTC Get Counter value : 0x%x\n", counter_value));
		}
		else {
			Ddim_Print(("CTC Get Counter value : NG  result=0x%x\n", ret));
		}
	}
	
	VOID Cycle_Time_Counter_Start(USHORT clock_length)
	{
		INT32			ret;
		T_DD_PMC_CTC_Ctrl	ctrl;
		
		// Set control data.
		ctrl->interrupt_enable	= 1;		// Interrupt enable
		ctrl->select_wait		= 0;		// Interrupt will be issued immediately after the complete of measuring.
		ctrl->clock_length		= clock_length;
		ret = Dd_PMC_CTC_Ctrl(&ctrl);
		if (ret != D_DDIM_OK) {
			Ddim_Print(("Dd_PMC_CTC_Ctrl : NG  result=0x%x\n", ret));
		}
		
		// Measure start.
		ret = Dd_PMC_CTC_Start((VP_CALLBACK)cycle_time_counter_callback);
		if (ret != D_DDIM_OK) {
			Ddim_Print(("Dd_PMC_CTC_Start : NG  result=0x%x\n", ret));
		}
	}
	
	@endcode

@}*//* --- end of dd_pmc_ctc_sequence */

#ifndef _DD_PMC_CTC_H_
#define _DD_PMC_CTC_H_

/** @weakgroup dd_pmc_ctc_definition
@{*/

#include "driver_common.h"

/*----------------------------------------------------------------------*/
/* Definition															*/
/*----------------------------------------------------------------------*/
// Return values
#define D_DD_PMC_CTC_INPUT_PARAM_ERR		(D_DD_PMC_CTC | D_DDIM_INPUT_PARAM_ERROR)	/**< Input parameter error. */
#define	D_DD_PMC_CTC_MACRO_BUSY_NG			(D_DD_PMC_CTC | D_DDIM_MACRO_BUSY_NG)		/**< Macro busy */
#define	D_DD_PMC_CTC_STATUS_ABNORMAL		(D_DD_PMC_CTC | D_DDIM_STATUS_ABNORMAL)		/**< Abnormal Status */
	
/*----------------------------------------------------------------------*/
/* Enumeration															*/
/*----------------------------------------------------------------------*/
// Nothing Special

/*----------------------------------------------------------------------*/
/* Structure  															*/
/*----------------------------------------------------------------------*/
/** CTC control data. */
typedef struct{
	UCHAR		interrupt_enable;		/**< Measuring End Interrupt Enable.<br>
											 0 : Interrupt disable.<br>
											 1 : Interrupt enable.																*/
	UCHAR		select_wait;			/**< Select Wait for Initialize.<br>
											 0 : Interrupt will be issued immediately after the complete of measuring.<br>
											 1 : interrupt will wait the end of the initialization sequence after measuring.	*/
	USHORT		clock_length;			/**< Observed Clock Length.<br>
											 Value range : 0~0xFFFF																*/
} T_DD_PMC_CTC_Ctrl;

/*----------------------------------------------------------------------*/
/* Global Data															*/
/*----------------------------------------------------------------------*/
// Nothing Special

/*----------------------------------------------------------------------*/
/* Macro																*/
/*----------------------------------------------------------------------*/
// Nothing Special

/* @} */	// dd_pmc_ctc_definition group

/** @weakgroup dd_pmc_ctc_api
@{*/
/*----------------------------------------------------------------------*/
/* Function																*/
/*----------------------------------------------------------------------*/
#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief  Set control data.
 * @param[in]	ctrl				CTC control data.<br>
 * @retval	D_DDIM_OK						Success.
 * @retval	D_DD_PMC_CTC_INPUT_PARAM_ERR	Input parameter error.
 */
extern	INT32 Dd_PMC_CTC_Ctrl( T_DD_PMC_CTC_Ctrl const* const ctrl );

/**
 * @brief  Measurement start.
 * @param[in]	callback			callback function pointer.<br>
 * @retval	D_DDIM_OK						Success.
 * @retval	D_DD_PMC_CTC_MACRO_BUSY_NG		CTC module busy.
 */
extern	INT32 Dd_PMC_CTC_Start( VP_CALLBACK callback );

/**
 * @brief  Measuring End Interrupt request.
 * @param[out]	status				Measuring end interrupt status.
 * @retval	D_DDIM_OK						Success.
 * @retval	D_DD_PMC_CTC_INPUT_PARAM_ERR	Input parameter error.
 */
extern	INT32 Dd_PMC_CTC_Get_Measuring_End_Status( UCHAR* status );

/**
 * @brief  Get Counter value.
 * @param[out]	counter_value		counted value of the measuring.
 * @retval VOID
 */
extern	INT32 Dd_PMC_CTC_Get_Counter_Value( ULONG* counter_value );

/**
 * @brief  Interrupt Handler.
 * @retval VOID
 */
extern	VOID Dd_PMC_CTC_Int_Handler( VOID );

#ifdef __cplusplus
}
#endif

/* @} */	// dd_pmc_ctc_api group

#endif	// _DD_PMC_CTC_H_
